import 'dart:async';
import './bloc_base.dart';
import '../model/player.dart';
class RoleBloc<T extends Player> implements BlocBase {
  final T roleData;
  StreamController<Map> _signStreamController = StreamController<Map>.broadcast();
  StreamController<List> _cardsStreamController = StreamController<List>.broadcast();
  StreamController<Map> _statusStreamController = StreamController<Map>();

  RoleBloc({this.roleData});

  Stream<Map> get signStream => _signStreamController.stream;
  StreamSink<Map> get signSink => _signStreamController.sink;

  Stream<List> get cardsStreamStream => _cardsStreamController.stream;
  StreamSink<List> get cardsStreamSink => _cardsStreamController.sink;

  Stream<Map> get statusStream => _statusStreamController.stream;
  StreamSink<Map> get statusSink => _statusStreamController.sink;

  Map get signData => {'id': roleData.roleId, 'uname': roleData.uname, 'sex': roleData.sex, 'asset': roleData.asset, 'isLandlord': roleData.isLandlord, 'maxCountCards': roleData.maxCountCards};
  List get cardsData => roleData.cards;
  Map get statusData => {'status': roleData.status, 'countDown': roleData.countDown, 'lastCards': roleData.lastCards};

  triggerStatus(PlayerStatus status) {
    roleData.triggerStatus(status);
    statusSink.add(statusData);
    if(status == PlayerStatus.ready) {
      this.setCards([]);
      this.setLandlord(false);
    }
  }

  void setMaxCountCards(int maxCount) {
    this.roleData.setMaxCountCards(maxCount);
    signSink.add(signData);
  }

  void getCards(List _cards) {
    roleData.getCards(_cards);
    cardsStreamSink.add(cardsData);
  }

  void setCards(List _cards, {bool sort=false}) {
    roleData.setCards(_cards, sort:sort);
    cardsStreamSink.add(cardsData);
  }

  void sortCards() {
    roleData.sortCards();
    cardsStreamSink.add(cardsData);
  }
  void setLandlord(bool isLandlord, [int landlordCardCount]) {
    if(isLandlord) {
      roleData.setMaxCountCards(landlordCardCount);
    }
    
    if(isLandlord != signData['isLandlord']) {
      roleData.setLandlord(isLandlord);
      signSink.add(signData);
    }
  }
  void setCountDown(int countDown) {
    roleData.setCountDown(countDown);
    statusSink.add(statusData);
  }
  void subCountDown() {
    setCountDown(statusData['countDown'] - 1);
  }

  void playCardsSuc({List sucCards}) {
    this.roleData.triggerStatus(PlayerStatus.waiting);
    
    if(sucCards != null) {
      this.roleData.playCards(sucCards);
      this.cardsStreamSink.add(this.cardsData);
    }
    this.statusSink.add(this.statusData);
  }

  void checkAsset(int newAsset) {
    if(newAsset != roleData.asset) {
      roleData.setAsset(newAsset);
      signSink.add(signData);
    }
  }

  void dispose() {
    signSink.close();
    _signStreamController.close();
    cardsStreamSink.close();
    _cardsStreamController.close();
    statusSink.close();
    _statusStreamController.close();
  }
}